using System;
using Microsoft.SPOT;

namespace mfXmlSerializer.NetduinoPlus2.TestApp
{
    public delegate void delStartExecuted(DateTime timestamp);
    public delegate void delStopExecuted(DateTime timestamp);
    public delegate void delResetExecuted(DateTime timestamp);

    public class Stopwatch
    {
        #region Fields
        DateTime _dtLastStart;
        TimeSpan _tsCurrentRuntime;

        #endregion

        #region CTOR

        public Stopwatch()
        {
            Reset();
        }
        #endregion

        #region Methods

        public void Start()
        {
            IsRunning = true;
            _dtLastStart = DateTime.Now;

            OnStartExecuted(_dtLastStart);
        }

        public void Stop()
        {
            if (_dtLastStart == DateTime.MinValue)
            {
                return;
            }
            var ts = DateTime.Now;
            LastRuntime = CalcRuntime(ts);
            IsRunning = false;

            OnStopExecuted(ts);
        }


        public void Reset()
        {
            _dtLastStart = DateTime.MinValue;
            LastRuntime = new TimeSpan(0, 0, 0, 0, 0);

            OnResetExecuted(DateTime.Now);
        }

        private TimeSpan CalcRuntime(DateTime timestamp)
        {
            return LastRuntime + (timestamp - _dtLastStart);
        }

        public static int ConvertTimeSpan2ElapsedMS(TimeSpan ts)
        {
            int elapsedMilliseconds = 0;

            elapsedMilliseconds += ts.Milliseconds;
            elapsedMilliseconds += (ts.Seconds > 0) ? ts.Seconds * 1000 : 0;
            elapsedMilliseconds += (ts.Minutes > 0) ? ts.Minutes * 60000 : 0;
            elapsedMilliseconds += (ts.Hours > 0) ? ts.Hours * 3600000 : 0;
            elapsedMilliseconds += (ts.Days > 0) ? ts.Days * 86400000 : 0;

            return elapsedMilliseconds;
        }
        #endregion

        #region Properties
        public TimeSpan LastRuntime
        {
            get
            {
                return _tsCurrentRuntime;
            }
            set
            {
                _tsCurrentRuntime = value;
            }
            //set//chaotical behavior!
            //{
            //    if (IsRunning)// too much fail-scenarios
            //    {
            //        throw new Exception(this.GetType() + " can't be setted in running-state");
            //    }

            //    //InternalRuntime += value;
            //    //InternalRuntime = InternalRuntime.Add(value);
            //    //InternalRuntime = new TimeSpan(InternalRuntime.Days + value.Days
            //                                    , InternalRuntime.Hours + value.Hours
            //                                    , InternalRuntime.Minutes + value.Minutes
            //                                    , InternalRuntime.Seconds + value.Seconds
            //                                    , InternalRuntime.Milliseconds + value.Milliseconds);
            //}
        }

        public int RuntimeInMilliseconds
        {
            get
            {
                return ConvertTimeSpan2ElapsedMS(LastRuntime);
            }
        }

        public bool IsRunning { get; private set; }
        #endregion

        #region Events

        public event delStartExecuted StartExecuted;
        protected void OnStartExecuted(DateTime timestamp)
        {
            if (StartExecuted != null)
            {
                StartExecuted(timestamp);
            }
        }

        public event delStopExecuted StopExecuted;
        protected void OnStopExecuted(DateTime timestamp)
        {
            if (StopExecuted != null)
            {
                StopExecuted(timestamp);
            }
        }


        public event delResetExecuted ResetExecuted;
        protected void OnResetExecuted(DateTime timestamp)
        {
            if (ResetExecuted != null)
            {
                ResetExecuted(timestamp);
            }
        }

        #endregion

    }
}
